package tools

import "sort"

// RemoveDuplicate 数组去重复
func RemoveDuplicate[T comparable](sliceList []T) []T {
	allKeys := make(map[T]bool)
	result := make([]T, 0, len(sliceList))

	for _, item := range sliceList {
		if _, value := allKeys[item]; !value {
			allKeys[item] = true

			result = append(result, item)
		}
	}

	return result
}

// RemoveDuplicateCustom 数组去重复（自定义比较）
func RemoveDuplicateCustom[T, K comparable](sliceList []T, keyFunc func(T) K) []T {
	allKeys := make(map[K]bool)
	result := make([]T, 0, len(sliceList))

	for _, item := range sliceList {
		key := keyFunc(item)
		if _, value := allKeys[key]; !value {
			allKeys[key] = true
			result = append(result, item)
		}
	}

	return result
}

// RemoveDuplicateBySlice 将数组src中存在于数组exclude中的元素去除
func RemoveDuplicateBySlice[T comparable](source, exclude []T) []T {
	excludedMap := make(map[T]bool, len(exclude))
	for _, item := range exclude {
		excludedMap[item] = true
	}

	result := make([]T, 0, len(source))

	for _, item := range source {
		if _, ok := excludedMap[item]; !ok {
			result = append(result, item)
		}
	}

	return result
}

// ConvertSliceType 转换数组类型
func ConvertSliceType[T1, T2 any](source []T1, convertFunc func(T1) T2) []T2 {
	result := make([]T2, 0, len(source))
	for _, item := range source {
		result = append(result, convertFunc(item))
	}

	return result
}

// SliceToMap 数组转map
func SliceToMap[T any](slice []T, keyFunc func(*T) string) map[string]*T {
	result := make(map[string]*T, len(slice))

	for idx := range slice {
		key := keyFunc(&slice[idx])
		result[key] = &slice[idx]
	}

	return result
}

// SliceToGroupMap 数组按指定key转为分组map
func SliceToGroupMap[T any](srcList []T, keyFunc func(*T) string) map[string][]*T {
	result := make(map[string][]*T, len(srcList))

	for idx := range srcList {
		key := keyFunc(&srcList[idx])
		group, ok := result[key]
		// 初始化分组切片
		if !ok {
			// TODO 确定初始大小
			result[key] = make([]*T, 0)
		}
		result[key] = append(group, &srcList[idx])
	}

	return result
}

// SliceToGroupValueMap 数组按指定key转为分组map，其中value通过函数生成
func SliceToGroupValueMap[T, P any](srcList []T, keyFunc func(T) string, valueFunc func(T) P) map[string][]P {
	result := make(map[string][]P, len(srcList))

	for idx := range srcList {
		key := keyFunc(srcList[idx])
		group, ok := result[key]
		// 初始化分组切片
		if !ok {
			// TODO 确定初始大小
			result[key] = make([]P, 0)
		}
		result[key] = append(group, valueFunc(srcList[idx]))
	}

	return result
}

// ConvertToNoPtr 指针数组转数组
func ConvertToNoPtr[T any](srcList []*T) []T {
	result := make([]T, 0, len(srcList))
	for idx := range srcList {
		result = append(result, *srcList[idx])
	}
	return result
}

// ConvertToPtr 数组转指针数组
func ConvertToPtr[T any](srcList []T) []*T {
	result := make([]*T, 0, len(srcList))
	for idx := range srcList {
		result = append(result, &srcList[idx])
	}
	return result
}

// Filter 过滤切片
func Filter[T any](slice []T, condition func(T) bool) []T {
	var filtered []T
	for _, item := range slice {
		if condition(item) {
			filtered = append(filtered, item)
		}
	}
	return filtered
}

// Sort 排序切片
func Sort[T any](slice []T, condition func(item1, item2 T) bool) []T {
	sort.Slice(slice, func(i, j int) bool {
		return condition(slice[i], slice[j])
	})
	return slice
}

// Paginate 对数据进行分页
func Paginate[T any](rooms []T, pageIndex, pageSize int) []T {
	start := (pageIndex - 1) * pageSize
	if start >= len(rooms) {
		return []T{}
	}
	end := start + pageSize
	if end > len(rooms) {
		end = len(rooms)
	}
	return rooms[start:end]
}
